package org.ejc.api.registration;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Date;

import org.apache.log4j.Category;
import org.ejc.persist.model.AccomodationType;
import org.ejc.persist.model.Address;
import org.ejc.persist.model.Convention;
import org.ejc.persist.model.ConventionExecutive;
import org.ejc.persist.model.ConventionRegistrant;
import org.ejc.persist.model.CountryCode;
import org.ejc.persist.model.LanguageIso;
import org.ejc.persist.model.Registrant;
import org.ejc.persist.model.RegistrantStatusType;
import org.ejc.persist.model.RegistrantType;
import org.ejc.persist.model.Transaction;
import org.ejc.util.EJCUtils;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Expression;

public class PreRegUpload {
	
	Category log = Category.getInstance(PreRegUpload.class);
	private int fails=0;
	private int success=0;
	private StringBuffer errors=null;
	
	public PreRegUpload(){
		fails=0;
		success=0;
		errors=new StringBuffer();
	}
	
	void processLine(String line) {
		Session s = null;
		org.hibernate.Transaction hibernateTransaction = null;
		String preRegCode="";
		try {
			s = EJCUtils.getHibernateSession();

			hibernateTransaction = s.beginTransaction();

			String[] lineSplit = line.split(",");

			preRegCode = lineSplit[0];
			String firstName = lineSplit[1];
			String lastName = lineSplit[2];
			String address1 = lineSplit[3];
			String address2 = lineSplit[4];
			String city = lineSplit[5];
			String age = lineSplit[6];

			String email = null;
			if (lineSplit.length > 7) {
				email = lineSplit[7];
			}
			
			//step1 create registrant details first name etc...
			Registrant registrant = new Registrant();
			registrant.setFirstName(firstName);
			registrant.setLastName(lastName);
			if (email != null && email.length() > 0) {
				registrant.setEmail(email);
			}

			//create their address
			Address a = new Address();
			a.setAddressLine1(address1);
			a.setAddressLine2(address2);
			a.setCityTown(city);

			//add their country to the address
			Criteria crit = s.createCriteria(CountryCode.class);
			crit.add(Expression.eq("countryIsoCode", preRegCode.substring(0, 2)));
			CountryCode c = (CountryCode) crit.list().get(0);
			a.setCountryCode(c);
			registrant.setAddress(a);

			//ok save the registrant and get the id
			Integer id = (Integer) s.save(registrant);
			registrant.setRegistrantId(id);

			//now create a conventionRegistrant.
			ConventionRegistrant convReg = new ConventionRegistrant();
			convReg.setRegistrantId(id);
			convReg.setRegistrant(registrant);
			convReg.setPreReg(preRegCode);
			convReg.setRegistrationDate(new Date());
			//TODO: Add util method to get current conv.
			Convention conv = (Convention) s.load(Convention.class,new Integer(1));

			//default lang at the min
			LanguageIso isoLang = new LanguageIso();
			isoLang.setLanguageId(1);
			convReg.setLanguageIso(isoLang);

			//pre-reg
			RegistrantStatusType regStatus = new RegistrantStatusType();
			regStatus.setId(2);
			convReg.setRegistrantStatusType(regStatus);
			convReg.setConvention(conv);

			//we are all Campers.
			AccomodationType tp = new AccomodationType();
			tp.setAccomodationTypeId(1);
			convReg.setAccomodationType(tp);
			
			RegistrantType type = new RegistrantType();
			type.setRegistrantTypeId(1);
			convReg.setRegistrantType(type);

			//save the convnetionRegistrant
			s.save(convReg);
			s.flush();

			// create the tx on the back of it.
			Transaction tx = new Transaction();
			tx.setConvention(conv);
			tx.setConventionExecutive((ConventionExecutive) s.load(
					ConventionExecutive.class, new Integer(-1)));
			tx.setRegistrant(registrant);
			tx.setTransactionDate(new Date());

			if (age == null) {
				tx.setTransactionAmount(new Double(90.00));
			} else if (age.equalsIgnoreCase("youth") || age.equalsIgnoreCase("child")) {
				tx.setTransactionAmount(new Double(45.00));
			} else if (age.equalsIgnoreCase("adult")) {
				tx.setTransactionAmount(new Double(90.00));
			} else if (age.equalsIgnoreCase("")) {
				log.fatal("NO AGE SET. Setting price to 90 euro!");
				tx.setTransactionAmount(new Double(90.00));
			}

			//tx.setStatus("PRE-REG-OK");

			s.save(tx);
			s.flush();
			//wahoo! all good. Lets commit and get the flock outta here
			hibernateTransaction.commit();
			success++;
		} catch (Exception e) {			
			//FFS. Theres always one eh !?
			fails++;
			errors.append("["+preRegCode+"],");
			log.fatal("Exception in processing Pre-Reg! code is ["+preRegCode+"]",e);
			log.fatal("Rolling back now ......");
			if(hibernateTransaction!=null){
				hibernateTransaction.rollback();
			}
		} finally {
			s.close();
		}

	}

	public void beginProcess() {
		log.fatal("About to begin processing file now ......");
		int counter=0;
		try {
			BufferedReader in = new BufferedReader(new FileReader(
					"/var/tmp/reg.csv"));
			String str;
			while ((str = in.readLine()) != null) {
				counter++;
				processLine(str);
			}
			in.close();

		} catch (Exception e) {
			e.printStackTrace();
		}
		log.fatal("End Processing of file now ..........");
		log.fatal("Processed ["+counter+"] records");
		log.fatal("["+success+"] were successfully added!");
		log.fatal("["+fails+"] had an issue!");
		log.fatal("Problem records are ->"+errors.toString()+"<-");
		
	}

}
